package com.soup.hummingbird;

import com.soup.hummingbird.module.method.bytebuddy.MethodCostTime;
import com.soup.hummingbird.module.threadpool.advice.ThreadPoolAdviceLogic;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;

import java.lang.instrument.Instrumentation;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 〈基于bytebuddy〉<br>
 *
 *     <a href='https://blog.csdn.net/wanxiaoderen/article/details/107079741'>study</a>
 *
 *
 *     https://notes.diguage.com/byte-buddy-tutorial/
 *
 * @author zhaoyi
 */
@Slf4j
public class PreMainV2 {

    //JVM 首先尝试在代理类上调用以下方法
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("--> " + agentArgs);
        new AgentBuilder.Default()
                .with(AgentBuilder.PoolStrategy.Default.EXTENDED)
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .type(ElementMatchers.nameStartsWith("com.soup")) // 指定需要拦截的类
                .transform((builder, typeDescription, classLoader, javaModule) -> {
                    // return builder.constructor(ElementMatchers.any()).intercept(MethodDelegation.to(MethodCostTime.class));

                    // return builder.visit(Advice.to(ThreadPoolAdviceLogic.class).on(ElementMatchers.isConstructor()));
                    return builder.method(ElementMatchers.any()) // 拦截任意方法
                            .intercept(MethodDelegation.to(MethodCostTime.class)); // 委托
                })
                .with(new AgentBuilder.Listener() {
                    @Override
                    public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {

                    }

                    @Override
                    public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {
                        System.out.println("onTransformation：" + typeDescription);
                    }

                    @Override
                    public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {

                    }

                    @Override
                    public void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {

                    }

                    @Override
                    public void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {

                    }

                }).installOn(inst);
    }

    //如果代理类没有实现上面的方法，那么 JVM 将尝试调用该方法
    public static void premain(String agentArgs) {

    }
}
